package com.hoshiicloud.stock.mq;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.hoshiicloud.common.constant.QueueConsts;
import com.hoshiicloud.common.exception.ServiceException;
import com.hoshiicloud.common.rpc.Response;
import com.hoshiicloud.common.utils.EncryptionUtil;
import com.hoshiicloud.goods.dto.sku.SkuDTO;
import com.hoshiicloud.purchase.Po;
import com.hoshiicloud.purchase.Podetail;
import com.hoshiicloud.saleorder.entity.OrderInfo;
import com.hoshiicloud.saleorder.entity.OrderMain;
import com.hoshiicloud.saleorder.param.OrderInfoQueryParam;
import com.hoshiicloud.stock.entity.WarehouseList;
import com.hoshiicloud.stock.feign.GoodsService;
import com.hoshiicloud.stock.feign.OrderService;
import com.hoshiicloud.stock.param.WarehouseListPageParam;
import com.hoshiicloud.stock.service.IWarehouseListService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @program: hoshiicloud
 * @description: rabmitMQ消息消费业务处理
 * @author: Mr.wu
 * @create: 2019-06-01 15:15
 **/
@Slf4j
@Component
public class RabbitMQConsumer {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private OrderService orderService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private IWarehouseListService warehouseListService;


    /**
     * 支付成功回调消息处理
     *
     * @param message
     * @throws Exception
     */
    @RabbitListener(queues = QueueConsts.PUSH_DO_QUEUE)
    @RabbitHandler
    public void payCallBackprocess(Message message) {
        try {
            log.info("接受回调消息" + message.toString());
            //获取请求体转换
            String body = new String(message.getBody());
            log.info("body:" + body);
            System.out.println(body);
            String json = new String(Base64.getMimeDecoder().decode(body.replace("\r\n", "")));
            Map<String, String> data = EncryptionUtil
                    .decryptData(json, RsaConfig.getClientPublicKey(),
                            RsaConfig.getServerPrivateKey());
            if (data == null) {
                //验签失败
                throw new ServiceException("解析消息失败，验签失败");
            } else {
                /**
                 * 从消息中解出主订单id
                 * 分配中状态订单执行出库策略
                 * 搜索子订单中为自供商品的部分
                 * 根据自供商品和采购单分别处理，生成出库单
                 * 出库单按主订单为单位生成，一张主订单生成一张对应的出库单
                 */
                log.info("data:" + JSON.toJSONString(data));
                Set<Long> mainOrderIdSet = EncryptionUtil.decryptData(json, RsaConfig.getClientPublicKey(), RsaConfig.getServerPrivateKey(), Set.class);
                List<Long> mainOrderIdList= new ArrayList<Long>(mainOrderIdSet);
                //查询主订单信息
                Response tempMainResult= orderService.getOrderMainByIds(mainOrderIdList);
                List<OrderMain> orderMainList=(List<OrderMain>) tempMainResult.getData();
                Map<Long,OrderMain> orderMainMap=new HashMap<>();
                for(OrderMain orderMain:orderMainList){
                    if(!orderMain.getOrderStatus().equals("3")){
                        //分配中状态才执行出库策略
                        mainOrderIdList.remove(orderMain.getId());
                    }
                    else{
                        orderMainMap.put(orderMain.getId(),orderMain);
                    }
                }
                if(mainOrderIdList.size()==0){
                    log.error("没有符合条件的订单,不执行出库策略");
                    return;
                }
                Map<Long,List<OrderInfo>> orderMap=new HashMap<>();
                Map<Long,List<Long>> baseSkuIdMap=new HashMap<>();
                Map<Long,List<Long>> extSkuIdMap=new HashMap<>();
                OrderInfoQueryParam orderInfoQueryParam=new OrderInfoQueryParam();
                orderInfoQueryParam.setMainId(mainOrderIdList);
                orderInfoQueryParam.setPageSize("1000");
                //查询主订单相关的子订单信息
                Response result= orderService.getOrderInfoPage(orderInfoQueryParam);
                IPage<OrderInfo> t=(IPage<OrderInfo>) result.getData();
                List<OrderInfo> tlist=t.getRecords();
                List<Long> baseSkuIdList=new ArrayList<>();
                List<Long> extSkuIdList=new ArrayList<>();
                for(OrderInfo order:tlist){
                    //根据主单分组
                    List<OrderInfo> orderInfoList=orderMap.get(order.getMainId());
                    if(orderInfoList==null){
                        orderInfoList=new ArrayList<OrderInfo>();
                        orderInfoList.add(order);
                        orderMap.put(order.getMainId(),orderInfoList);
                    }
                    //保存所有扩展sku的id用于查询
                    extSkuIdList.add(order.getSkuId());
                }
                //TODO 获取dto方法待添加缓存
                Response<Map<Long, SkuDTO>> skuDtoResult= goodsService.getSkuStockByIds(extSkuIdList);
                Map<Long,SkuDTO> skuDTOMap=skuDtoResult.getData();
                Map<Long, Po> poMap=new HashMap<>();
                Map<Long,List<Podetail>> poDetailListMap=new HashMap<>();
                Map<Long,String> exceptionalMsgMap=new HashMap<>();
                boolean purchaseSuccess=true;
                Long vendorId=null;
                WarehouseListPageParam warehouseListPageParam=new WarehouseListPageParam();
                warehouseListPageParam.setPageSize(1000l);
                warehouseListPageParam.setDeleted(0);
                for(Map.Entry<Long,List<OrderInfo>> entry:orderMap.entrySet()){
                    List<OrderInfo> temp=entry.getValue();
                    WarehouseList warehouseList=null;
                    purchaseSuccess=true;
                    mainOrder:
                    for (OrderInfo order:temp){
                        SkuDTO skuDetail=skuDTOMap.get(order.getSkuId());
                        String exceptionalMsg=exceptionalMsgMap.get(order.getMainId());

                        if(exceptionalMsg==null){
                            exceptionalMsg="";
                            exceptionalMsgMap.put(order.getMainId(),exceptionalMsg);
                        }
                        if(skuDetail.getVendorSelf().equals(1)){
                            //TODO 自供商品生成出库单流程
                            continue;
                        }
                        else{
                            //找到对应的采购单,采购环节已指定了供应商和仓库
                        }
                        //根据采购策略判断是否生成采购单
                        if(skuDetail.getStrategy().equals(1)){
                            //指定的供应商为空且非自供商品,产生出库异常工单
                            if(skuDetail.getVendorId()==null){
                                exceptionalMsg+="编号为"+order.getId()+"的订单中的编号为"+skuDetail.getSkuId()+"的商品没有指定供应商，请及时处理;";
                                purchaseSuccess=false;
                                continue;
                            }
                            else{
                                //指定供应商
                                //找到指定供应商的仓库，判断库存数量是否足够
                                warehouseListPageParam.setVendor(skuDetail.getVendorId());
                            }
                        }
                        else if(skuDetail.getStrategy().equals(2)){
                            //系统派单
                            //如果找不到合适的供应商采购,产生采购异常工单
                            //对应商品供应商
                            //找到供应商的仓库，判断库存数量是否足够
                            //TODO 选择成本最低的供应商
                            warehouseListPageParam.setVendor(null);
                        }
                        //系统派单和指定供应商的区别是查询条件是否设置

                        warehouseListPageParam.setBalance(new BigDecimal(order.getQuantity()));
                        //根据基础skuid查找
                        warehouseListPageParam.setSkuId(skuDetail.getSkuId());
                        IPage<WarehouseList> tStockResult= warehouseListService.List(warehouseListPageParam);
                        if(tStockResult==null){
                            //TODO 查询库存业务失败,异常处理
                            //系统异常跳过后续订单处理
                            exceptionalMsg+="编号为"+order.getId()+"的订单采购策略查询库存发生异常,请联系技术部及时处理";
                            purchaseSuccess=false;
                            continue;
                        }

                        IPage<WarehouseList> warehouseListIPage= tStockResult;
                        List<WarehouseList> warehouseLists=warehouseListIPage.getRecords();
                        if(warehouseLists.size()==0){
                            exceptionalMsg+="编号为"+order.getId()+"的订单中的编号为"+skuDetail.getSkuId()+"的商品无法找到符合条件的供应商，请及时处理;";
                            purchaseSuccess=false;
                            continue;
                        }
                        if(!purchaseSuccess){
                            continue;
                        }
                        else{
                            //生成采购单明细
                            warehouseList= warehouseLists.get(0);
                            vendorId=warehouseList.getVendor();
                            //生成采购单与采购单明细
                            List<Podetail> podetailList=poDetailListMap.get(vendorId);
                            if(podetailList==null){
                                podetailList=new ArrayList<>();
                                poDetailListMap.put(vendorId,podetailList);
                            }
                            Podetail podetail=new Podetail();
                            podetail.setSpuName(skuDetail.getSpuTitle());
                            podetail.setSkuName(skuDetail.getSkuTitle());
                            podetail.setSpuNo(skuDetail.getSpuNo());
                            podetail.setSpuId(skuDetail.getSpuId());
                            podetail.setSkuNo(warehouseList.getSkuno());
                            podetail.setSkuId(skuDetail.getSkuId());
                            podetail.setUnit(warehouseList.getUnit());
                            //规格
                            podetail.setSku(warehouseList.getSpec());
                            podetail.setUnitPrice(skuDetail.getGoodsPrice());
                            podetail.setQuantity(order.getQuantity());


                            podetail.setStatus(1);

                            //税率暂时默认为0
                            podetail.setRate(BigDecimal.ZERO);
                            podetail.setAmount(podetail.getUnitPrice().multiply(new BigDecimal(podetail.getQuantity()).setScale(2)));
                            podetail.setRatefee(podetail.getAmount().multiply(podetail.getRate()));
                            //合计金额 = 金额+ 税额
                            podetail.setTotalAmount(podetail.getAmount().add(podetail.getRatefee()));
                            podetailList.add(podetail);
                            Po po=poMap.get(vendorId);
                            if(po==null){
                                OrderMain orderMain=orderMainMap.get(order.getMainId());
                                po=new Po();
                                po.setCompanyId(warehouseList.getCompanyid());
                                po.setPlatformId(warehouseList.getPlatformid());
                                po.setStoreId(warehouseList.getStoreid());
                                po.setVendorId(vendorId);
                                po.setMemberId(order.getMemberId());
                                po.setAddress(orderMain.getAddress());

                                //订单状态  0-初始下单 2-已确认 3-执行中 4-已完成 5-已作废
                                po.setStatus(0);
                                //结算状态  1-已结算  0-未结算
                                po.setSettleStatus(0);
                                //结算金额
                                po.setSettleAmount(podetail.getTotalAmount());
                                po.setOrderAmount(podetail.getTotalAmount());
                                po.setOrderCount(podetail.getQuantity());
                                po.setSalesOrderId(orderMain.getId());
                                po.setCreatedBy("系统生成");
                                po.setCreatedTime(LocalDateTime.now());
                                poMap.put(vendorId,po);
                            }else{
                                po.setSettleAmount(po.getSettleAmount().add(podetail.getTotalAmount()));
                                po.setOrderAmount(po.getOrderAmount().add(podetail.getTotalAmount()));
                                po.setOrderCount(po.getOrderCount()+podetail.getQuantity());
                            }
                        }
                    }
                }

            }
            //业务处理
        } catch (Exception e) {
            log.error("{}", e.getMessage());
        }

    }
}
